﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace Tosi
{
    class Statistics
    {
        private int CarNr;
        private int StreetNr;
        private int JunctionNr;
        private int NrOfMoves;
        public StatTable t;

        public Statistics()                 // lefoglalom a helyet
        {
            CarNr = Var.CarNr;
            StreetNr = Var.STREETS.Length;
            JunctionNr = Var.JUNCTIONS.Length;
            NrOfMoves = Var.Iterations;
            t = null;
        }
        public void setStatTable(ref StatTable t1)
        {
            t = t1;
        }
        public void startIterationStat(int i)
        {
            
            streetLoadStat(i);          // ut telitettsege
            waitingTimeStat(i);         // varakozasi ido
            waitingCarsStat(i);         // varakozo kocsik szama
            junctionCongestionStat(i);  // csomopont zsufoltsag
            //speedStat(i);
            //lightStat(i);
            //carsPerStreetStat(i);
            //carsInJunctionsStat(i);
            // junctionLoadStat(i);
        }
        public void startIntervalStat()
        {
 
            intWaitingCars();           // varakozo kocsik szama
            intWaitingTime();          // lampara ha van van nincs varokozo kocsi
            intStreetLoad();            // ut telitettsege
            intJunctionCongestion();        // csomopont zsufoltsag
            intWaitingTimePerJunction();    //avg
            intWaitingCarsPerJunction();    // avg
            //intLightState();
            //intJunctionLoadC();
            //intJunctionLoadCarNr();
            //intSumWaitingTime();
            //intAvgWaitingTime();
            //intAvgJunctionLoad();
            //intAverageSpeedStat();
            //intSumCarsInJunction();

        }
        
       
        public void streetLoadStat(int i)           // %-ban kifejezve
        {
            for (int j = 0; j < StreetNr; j++)
            {
                if (Var.STREETS[j].getMaxCars() == 0)
                    t.StreetLoad[i, j] = 0;
                else
                {
                    int count = Var.STREETS[j].getCars().Count;
                    int max = Var.STREETS[j].getMaxCars();
                    t.StreetLoad[i, j] = (double)count * 100 / max;
                    Var.STREETS[j].myLight.setStreetLoad(t.StreetLoad[i, j]);
                }
            }
        }
        
        public void junctionCongestionStat(int i)                       // zsufoltsag
        {
            for (int j = 0; j < JunctionNr; j++)
            {
                List<Street> st = Var.JUNCTIONS[j].getInStreets();   // j. csomoponthoz tartozo utak
                int len = st.Count();
                double sum = 0;
                double maxCarNr = 0;
                for (int k = 0; k < len; k++)
                {
                    maxCarNr += st[k].getMaxCars();
                    List<Car> car = st[k].getCars();               // j. csomopont k.uthoz tartozo kocsik
                    foreach (Car c in car)
                    {
                        if (c.getTempSpeed() == 0)
                            sum += 1;
                    }
                }
                t.JunctionCongestion[i, j] = sum * 100 / maxCarNr;
                //Console.WriteLine("{0} -> {1}",j, Var.JunctionCongestion[i, j]);
                Var.gr.setJunctionState(j, t.JunctionCongestion[i, j]);
            }

        }
        public void waitingTimeStat(int i)
        {
            for (int j = 0; j < StreetNr; j++)
            {
                if (Var.STREETS[j].cars.Count == 0)
                    t.WaitingTimePerLight[i, j] = 0;
                else if (Var.STREETS[j].cars[0].getTempSpeed() == 0)
                    t.WaitingTimePerLight[i, j] = 1;
                else
                    t.WaitingTimePerLight[i, j] = 0;
            }
        }
        public void waitingCarsStat(int i)
        {
            for (int j = 0; j < StreetNr; j++)
            {
                int sum = 0;
                List<Car> c = Var.STREETS[j].getCars();
                foreach (Car car in c)
                {
                    if (car.getTempSpeed() == 0)
                        sum++;
                }
                t.WaitingCarsPerLight[i, j] = sum;
                sum = 0;
            }

        }
//public void junctionLoadStat(int i)             // telitettseg
        //{
        //    List<Street> st = new List<Street>();
        //    int sumCarNr = 0;
        //    int maxCarNr = 0;
        //    for (int j = 0; j < JunctionNr; j++)
        //    {
        //        st = Var.JUNCTIONS[j].getInStreets();

        //        foreach (Street s in st)
        //        {
        //            sumCarNr += s.getCars().Count;
        //            maxCarNr += s.getMaxCars();
        //        }
                
        //        t.JunctionLoad[i,j] = (double)sumCarNr / maxCarNr;
        //    }
        //}

        /*public void speedStat(int i)                // i = a hanyadik kirajzolasnal vagyunk
       {
           for (int j = 0; j < CarNr; j++)
           {
               t.CarSpeed[i, j] = Var.CARS[j].getTempSpeed();
           }

       }
       public void lightStat(int i)
       {
           for (int j = 0; j < StreetNr; j++)
           {
               t.LightState[i, j] = Var.STREETS[j].getMyLight().getState();
           }
       }*/
        //public void carsPerStreetStat(int i)
        //{
        //    for (int j = 0; j < StreetNr; j++)
        //    {
        //        t.CarsOnStreet[i, j] = Var.STREETS[j].cars.Count;
        //    }
        //}
        /*public void carsInJunctionsStat(int i)              // csak a 0-as tempSpeedeseket tartalmazza
        {
            for (int j = 0; j < JunctionNr; j++)
            {
                List<Street> st = Var.JUNCTIONS[j].getInStreets();   // j. csomoponthoz tartozo utak
                int len = st.Count();
                int sum = 0;
                for (int k = 0; k < len; k++)
                {
                    List<Car> car = st[k].getCars();               // j. csomopont k.uthoz tartozo kocsik
                    foreach (Car c in car)
                    {
                        if (c.getTempSpeed() == 0)
                            sum += 1;
                    }
                    st[k].myLight.setStationaryCars(sum);
                }
                t.CarsInJunction[i, j] = (sum);
            }
        }*/

        // INTERVAL STAT
       public void intWaitingCars()
       {
           int sum = 0;
           for (int i = 0; i < StreetNr; i++)
           {
               for (int j = 0; j < NrOfMoves; j++)
                   sum += t.WaitingCarsPerLight[j, i];

               t.AvgWaitingCarsPerStreet[i] = sum/NrOfMoves;
               sum = 0;
           }

       }
       public void intWaitingTime()  
       {
           int sum = 0;
           for (int i = 0; i < StreetNr; i++)
           {
               for (int j = 0; j < NrOfMoves; j++)
                   sum += t.WaitingTimePerLight[j, i];

               t.SumWaitingTimePerStreet[i] = sum;
               sum = 0;
           }
       }
       public void intStreetLoad()
       {
           double sum = 0;
           for (int i = 0; i < StreetNr; i++)
           {
               for (int j = 0; j < NrOfMoves; j++)
                   sum += t.WaitingTimePerLight[j, i];

               t.AvgStreetLoad[i] = sum/NrOfMoves;
               sum = 0;
           }

       }
        
        public void intJunctionCongestion()
        {
            for (int i = 0; i < JunctionNr; i++)
            {
                double sum = 0;
                for (int j = 0; j < NrOfMoves; j++)
                {
                    sum += t.JunctionCongestion[j, i];
                }
                t.IntJunctionCongestion[i] = sum/NrOfMoves;
            }
        }
        public void intWaitingTimePerJunction()
        {
            for (int i = 0; i < JunctionNr; i++)
            {
                int sum = 0;
                for (int j = 0; j < Var.JUNCTIONS[i].inStreets.Count; j++ )
                {
                    sum += t.SumWaitingTimePerStreet[Var.JUNCTIONS[i].inStreets[j].myLight.getId()];
                }
                t.AvgWaitingTimePerJunction[i] = sum / Var.JUNCTIONS[i].inStreets.Count;
            }

        }
        public void intWaitingCarsPerJunction()
        {
            for (int i = 0; i < JunctionNr; i++)
            {
                double sum = 0;
                for (int j = 0; j < Var.JUNCTIONS[i].inStreets.Count; j++)
                {
                    sum += t.AvgWaitingCarsPerStreet[Var.JUNCTIONS[i].inStreets[j].myLight.getId()];
                }
                t.AvgWaitingCarsPerJunction[i] = sum / Var.JUNCTIONS[i].inStreets.Count;
            }
        }
       
        public void intSumWaitingTime()
        {
            int sum = 0;
            for (int i = 0; i < StreetNr; i++)
            {
                for (int j = 0; j < NrOfMoves; j++)
                    sum += t.WaitingTimePerLight[j, i];

                t.SumWaitingTimePerStreet[i] = sum;
                sum = 0;
            }
        }
        //public void intAvgWaitingTime()
        //{
        //    for (int i = 0; i < StreetNr; i++)
        //    {
        //        t.AvgWaitingTime[i] = (double)t.SumWaitingTimePerStreet[i] / NrOfMoves;
        //    }
        //}
        //public void intAvgJunctionLoad()
        //{
        //    double sum = 0;
        //    for (int i = 0; i < JunctionNr; i++)
        //    {
        //        for (int j = 0; j < NrOfMoves; j++)
        //        {
        //            sum += t.JunctionLoad[j, i];
        //        }
        //        t.AvgJunctionLoad[i] = sum *100/ NrOfMoves;
        //        sum = 0;
        //    }
        //}

        /*public void intAverageSpeedStat()
        {
            for (int i = 0; i < CarNr; i++)
            {
                double sum = 0;
                for (int j = 0; j < NrOfMoves; j++)
                {
                    sum += t.CarSpeed[j, i];
                }
                t.IntAverageCarSpeed[i] = sum / NrOfMoves;
            }
        }
        public void intLightState()
        {
            for (int i = 0; i < StreetNr; i++)
            {
                int sum = 0;
                for (int j = 0; j < NrOfMoves; j++)
                {
                    sum += t.LightState[j, i];
                }
                t.IntSumLightState[i, 0] = sum;
                t.IntSumLightState[i, 1] = NrOfMoves - sum;
            }
        }
        public void intSumCarsInJunction()
        {
            for (int i = 0; i < JunctionNr; i++)
            {
                int sum = 0;
                for (int j = 0; j < NrOfMoves; j++)
                {
                    sum += t.CarsInJunction[j, i];
                }
                t.IntSumCarsOnJunction[i] = sum;
            }
        }*/
        /*public void intJunctionLoadC()
       {
           double capacity = 0;
           foreach (Street s in Var.STREETS)
           {
               capacity += s.getMaxCars();
           }

           for (int i = 0; i < JunctionNr; i++)
           {
               double sum = 0;
               for (int j = 0; j < NrOfMoves; j++)
               {
                   sum += t.CarsInJunction[j, i];
               }
               t.IntJunctionLoadPerCapacity[i] = sum / capacity * 100;
           }
       }
       public void intJunctionLoadCarNr()
       {
           double carNr = Var.CARS.Length;

           for (int i = 0; i < JunctionNr; i++)
           {
               double sum = 0;
               for (int j = 0; j < NrOfMoves; j++)
               {
                   sum += t.CarsInJunction[j, i];
               }
               t.IntJunctionLoadPerCarNr[i] = sum * 100 / carNr;
           }
       }*/
    }
}
